home *** CD-ROM | disk | FTP | other *** search
Wrap
# Source Generated with Decompyle++ # File: in.pyc (Python 2.6) import os import re import gtk from gtk import gdk import gio import gedit from Library import Library from Snippet import Snippet from Placeholder import * from SnippetComplete import SnippetComplete class Document: TAB_KEY_VAL = (gtk.keysyms.Tab, gtk.keysyms.ISO_Left_Tab) SPACE_KEY_VAL = (gtk.keysyms.space,) def __init__(self, instance, view): self.view = None self.instance = instance self.placeholders = [] self.active_snippets = [] self.active_placeholder = None self.signal_ids = { } self.ordered_placeholders = [] self.update_placeholders = [] self.jump_placeholders = [] self.language_id = 0 self.timeout_update_id = 0 Library().ref(None) self.set_view(view) def stop(self): if self.timeout_update_id != 0: gobject.source_remove(self.timeout_update_id) self.timeout_update_id = 0 del self.update_placeholders[:] del self.jump_placeholders[:] Library().unref(None) self.set_view(None) self.instance = None self.active_placeholder = None def disconnect_signal(self, obj, signal): if (obj, signal) in self.signal_ids: obj.disconnect(self.signal_ids[(obj, signal)]) del self.signal_ids[(obj, signal)] def connect_signal(self, obj, signal, cb): self.disconnect_signal(obj, signal) self.signal_ids[(obj, signal)] = obj.connect(signal, cb) def connect_signal_after(self, obj, signal, cb): self.disconnect_signal(obj, signal) self.signal_ids[(obj, signal)] = obj.connect_after(signal, cb) def _set_view(self, view): if self.view: buf = self.view.get_buffer() signals = { self.view: ('key-press-event', 'destroy', 'notify::editable', 'drag-data-received'), buf: ('notify::language', 'changed', 'cursor-moved', 'insert-text') } for obj, sig in signals.items(): for s in sig: self.disconnect_signal(obj, s) for snippet in list(self.active_snippets): self.deactivate_snippet(snippet, True) self.view = view if view != None: buf = view.get_buffer() self.connect_signal(view, 'destroy', self.on_view_destroy) if view.get_editable(): self.connect_signal(view, 'key-press-event', self.on_view_key_press) self.connect_signal(buf, 'notify::language', self.on_notify_language) self.connect_signal(view, 'notify::editable', self.on_notify_editable) self.connect_signal(view, 'drag-data-received', self.on_drag_data_received) self.update_language() elif self.language_id != 0: langid = self.language_id self.language_id = None if self.instance: self.instance.language_changed(self) Library().unref(langid) def set_view(self, view): if view == self.view: return None self._set_view(view) def update_language(self): lang = self.view.get_buffer().get_language() if lang == None and self.language_id == None: return None if lang and lang.get_id() == self.language_id: return None langid = self.language_id if self.instance: self.instance.language_changed(self) if langid != 0: Library().unref(langid) Library().ref(self.language_id) def accelerator_activate(self, keyval, mod): if not (self.view) or not self.view.get_editable(): return None accelerator = gtk.accelerator_name(keyval, mod) snippets = Library().from_accelerator(accelerator, self.language_id) snippets_debug('Accel!') if len(snippets) == 0: return False if len(snippets) == 1: self.apply_snippet(snippets[0]) else: return self.show_completion(snippets) return len(snippets) == 0 def first_snippet_inserted(self): buf = self.view.get_buffer() self.connect_signal(buf, 'changed', self.on_buffer_changed) self.connect_signal(buf, 'cursor-moved', self.on_buffer_cursor_moved) self.connect_signal_after(buf, 'insert-text', self.on_buffer_insert_text) def last_snippet_removed(self): buf = self.view.get_buffer() self.disconnect_signal(buf, 'changed') self.disconnect_signal(buf, 'cursor-moved') self.disconnect_signal(buf, 'insert-text') def current_placeholder(self): buf = self.view.get_buffer() piter = buf.get_iter_at_mark(buf.get_insert()) found = [] for placeholder in self.placeholders: begin = placeholder.begin_iter() end = placeholder.end_iter() if piter.compare(begin) >= 0 and piter.compare(end) <= 0: found.append(placeholder) continue if self.active_placeholder in found: return self.active_placeholder if len(found) > 0: return found[0] return None def advance_placeholder(self, direction): buf = self.view.get_buffer() piter = buf.get_iter_at_mark(buf.get_insert()) found = None current = None next = None length = len(self.placeholders) placeholders = list(self.placeholders) if self.active_placeholder: begin = self.active_placeholder.begin_iter() end = self.active_placeholder.end_iter() if piter.compare(begin) >= 0 and piter.compare(end) <= 0: current = self.active_placeholder currentIndex = placeholders.index(self.active_placeholder) if direction == 1: nearest = lambda w, x, y, z: if not w.compare(x) <= 0 and not z: passx.compare(z.begin_iter()) < 0 indexer = lambda x: x < length - 1 else: nearest = lambda w, x, y, z: if not w.compare(x) >= 0 and not z: passx.compare(z.begin_iter()) >= 0 indexer = lambda x: x > 0 for index in range(0, length): placeholder = placeholders[index] begin = placeholder.begin_iter() end = placeholder.end_iter() if nearest(piter, begin, end, found): foundIndex = index found = placeholder if piter.compare(begin) >= 0 and piter.compare(end) <= 0 and current == None: currentIndex = index current = placeholder continue if current and current != found: if (current.begin_iter().compare(found.begin_iter()) == 0 or current.end_iter().compare(found.begin_iter()) == 0) and self.active_placeholder and current.begin_iter().compare(self.active_placeholder.begin_iter()) == 0: current = self.active_placeholder currentIndex = placeholders.index(current) found = current if current and current == found: if indexer(currentIndex): next = placeholders[currentIndex + direction] elif found: next = found elif length > 0: next = self.placeholders[0] return (current, next) def next_placeholder(self): return self.advance_placeholder(1) def previous_placeholder(self): return self.advance_placeholder(-1) def cursor_on_screen(self): buf = self.view.get_buffer() self.view.scroll_mark_onscreen(buf.get_insert()) def set_active_placeholder(self, placeholder): self.active_placeholder = placeholder def goto_placeholder(self, current, next): last = None if current: current.leave() if current.__class__ == PlaceholderEnd: last = current self.set_active_placeholder(next) if next: next.enter() if next.__class__ == PlaceholderEnd: last = next if last: for snippet in list(self.active_snippets): if snippet.placeholders[0] == last: self.deactivate_snippet(snippet) break continue self.cursor_on_screen() return next != None def skip_to_next_placeholder(self): (current, next) = self.next_placeholder() return self.goto_placeholder(current, next) def skip_to_previous_placeholder(self): (current, prev) = self.previous_placeholder() return self.goto_placeholder(current, prev) def env_get_selected_text(self, buf): bounds = buf.get_selection_bounds() if bounds: return buf.get_text(bounds[0], bounds[1]) return '' def env_get_current_word(self, buf): (start, end) = buffer_word_boundary(buf) return buf.get_text(start, end) def env_get_filename(self, buf): uri = buf.get_uri() if uri: return buf.get_uri_for_display() return '' def env_get_basename(self, buf): uri = buf.get_uri() if uri: return os.path.basename(buf.get_uri_for_display()) return '' def update_environment(self): buf = self.view.get_buffer() variables = { 'GEDIT_SELECTED_TEXT': self.env_get_selected_text, 'GEDIT_CURRENT_WORD': self.env_get_current_word, 'GEDIT_FILENAME': self.env_get_filename, 'GEDIT_BASENAME': self.env_get_basename } for var in variables: os.environ[var] = variables[var](buf) def uses_current_word(self, snippet): matches = re.findall('(\\\\*)\\$GEDIT_CURRENT_WORD', snippet['text']) for match in matches: if len(match) % 2 == 0: return True return False def apply_snippet(self, snippet, start = None, end = None): if not snippet.valid: return False buf = self.view.get_buffer() s = Snippet(snippet) if not start: start = buf.get_iter_at_mark(buf.get_insert()) if not end: end = buf.get_iter_at_mark(buf.get_selection_bound()) if start.equal(end) and self.uses_current_word(s): (start, end) = buffer_word_boundary(buf) self.update_environment() (current, next) = self.next_placeholder() if current and current.__class__ == PlaceholderEnd: self.goto_placeholder(current, None) buf.begin_user_action() buf.delete(start, end) holders = len(self.placeholders) if len(self.active_snippets) == 0: self.first_snippet_inserted() sn = s.insert_into(self, start) self.active_snippets.append(sn) keys = filter((lambda x: x > 0), sn.placeholders.keys()) if len(keys) == 0: buf.place_cursor(sn.begin_iter()) else: self.goto_placeholder(self.active_placeholder, sn.placeholders[keys[0]]) buf.end_user_action() return True def get_tab_tag(self, buf): end = buf.get_iter_at_mark(buf.get_insert()) start = end.copy() word = None if start.backward_word_start(): tmp = start.copy() tmp.forward_word_end() if tmp.equal(end): word = buf.get_text(start, end) else: start = end.copy() else: start = end.copy() if not word or word == '': if start.backward_char(): word = start.get_char() if word.isalnum() or word.isspace(): return (None, None, None) else: return (None, None, None) start.backward_char() return (word, start, end) def run_snippet(self): if not self.view: return False buf = self.view.get_buffer() (word, start, end) = self.get_tab_tag(buf) if not word: return self.skip_to_next_placeholder() snippets = Library().from_tag(word, self.language_id) if snippets: if len(snippets) == 1: return self.apply_snippet(snippets[0], start, end) return self.show_completion(snippets) snippets return self.skip_to_next_placeholder() def deactivate_snippet(self, snippet, force = False): buf = self.view.get_buffer() remove = [] for tabstop in snippet.placeholders: if tabstop == -1: placeholders = snippet.placeholders[-1] else: placeholders = [ snippet.placeholders[tabstop]] for placeholder in placeholders: if placeholder in self.placeholders: if placeholder in self.update_placeholders: placeholder.update_contents() self.update_placeholders.remove(placeholder) elif placeholder in self.jump_placeholders: placeholder[0].leave() remove.append(placeholder) continue for placeholder in remove: if placeholder == self.active_placeholder: self.active_placeholder = None self.placeholders.remove(placeholder) self.ordered_placeholders.remove(placeholder) placeholder.remove(force) snippet.deactivate() self.active_snippets.remove(snippet) if len(self.active_snippets) == 0: self.last_snippet_removed() def move_completion_window(self, complete, x, y): MARGIN = 15 screen = self.view.get_screen() width = screen.get_width() height = screen.get_height() (cw, ch) = complete.get_size() if x + cw > width: x = width - cw - MARGIN elif x < MARGIN: x = MARGIN if y + ch > height: y = height - ch - MARGIN elif y < MARGIN: y = MARGIN complete.move(x, y) def show_completion(self, preset = None): buf = self.view.get_buffer() bounds = buf.get_selection_bounds() prefix = None if not bounds and not preset: (prefix, start, end) = self.get_tab_tag(buf) if not prefix: end = buf.get_iter_at_mark(buf.get_insert()) if not preset or len(preset) == 0: nodes = Library().get_snippets(None) if self.language_id: nodes += Library().get_snippets(self.language_id) if prefix and len(prefix) == 1 and not prefix.isalnum(): hasnodes = False for node in nodes: if node['tag'] and node['tag'].startswith(prefix): hasnodes = True break continue if not hasnodes: prefix = None complete = SnippetComplete(nodes, prefix, False) else: complete = SnippetComplete(preset, None, True) complete.connect('snippet-activated', self.on_complete_row_activated) rect = self.view.get_iter_location(end) win = self.view.get_window(gtk.TEXT_WINDOW_TEXT) (x, y) = self.view.buffer_to_window_coords(gtk.TEXT_WINDOW_TEXT, rect.x + rect.width, rect.y) (xor, yor) = win.get_origin() self.move_completion_window(complete, x + xor, y + yor) return complete.run() def update_snippet_contents(self): self.timeout_update_id = 0 for placeholder in self.update_placeholders: placeholder.update_contents() for placeholder in self.jump_placeholders: self.goto_placeholder(placeholder[0], placeholder[1]) del self.update_placeholders[:] del self.jump_placeholders[:] return False def on_view_destroy(self, view): self.stop() def on_complete_row_activated(self, complete, snippet): buf = self.view.get_buffer() bounds = buf.get_selection_bounds() if bounds: self.apply_snippet(snippet.data, None, None) else: (word, start, end) = self.get_tab_tag(buf) self.apply_snippet(snippet.data, start, end) def on_buffer_cursor_moved(self, buf): piter = buf.get_iter_at_mark(buf.get_insert()) for snippet in list(self.active_snippets): if snippet.begin_mark.get_deleted() or snippet.end_mark.get_deleted(): self.deactivate(snippet) continue begin = snippet.begin_iter() end = snippet.end_iter() if piter.compare(begin) < 0 or piter.compare(end) > 0: self.deactivate_snippet(snippet) continue current = self.current_placeholder() if current != self.active_placeholder: if self.active_placeholder: self.jump_placeholders.append((self.active_placeholder, current)) if self.timeout_update_id == 0: self.timeout_update_id = gobject.timeout_add(0, self.update_snippet_contents) self.set_active_placeholder(current) def on_buffer_changed(self, buf): current = self.current_placeholder() if current: if current not in self.update_placeholders: self.update_placeholders.append(current) if self.timeout_update_id == 0: self.timeout_update_id = gobject.timeout_add(0, self.update_snippet_contents) def on_buffer_insert_text(self, buf, piter, text, length): ctx = get_buffer_context(buf) if not ctx and not (self.active_placeholder): return None if not ctx: ctx = self.active_placeholder if ctx not in self.ordered_placeholders: return None begin = ctx.begin_iter() end = ctx.end_iter() idx = self.ordered_placeholders.index(ctx) for placeholder in self.ordered_placeholders: if placeholder == ctx: continue ob = placeholder.begin_iter() oe = placeholder.end_iter() if ob.compare(begin) == 0: if not oe or oe.compare(end) == 0: oidx = self.ordered_placeholders.index(placeholder) if oidx > idx and ob: buf.move_mark(placeholder.begin, end) elif oidx < idx and oe: buf.move_mark(placeholder.end, begin) oe if ob.compare(begin) >= 0 and ob.compare(end) < 0 and oe and oe.compare(end) >= 0: buf.move_mark(placeholder.begin, end) continue if (oe or oe.compare(begin) > 0) and ob.compare(begin) <= 0: buf.move_mark(placeholder.end, begin) continue def on_notify_language(self, buf, spec): self.update_language() def on_notify_editable(self, view, spec): self._set_view(view) def on_view_key_press(self, view, event): library = Library() if not (event.state & gdk.CONTROL_MASK) and not (event.state & gdk.MOD1_MASK) and event.keyval in self.TAB_KEY_VAL: if not event.state & gdk.SHIFT_MASK: return self.run_snippet() return self.skip_to_previous_placeholder() event.keyval in self.TAB_KEY_VAL if event.state & gdk.CONTROL_MASK and not (event.state & gdk.MOD1_MASK) and not (event.state & gdk.SHIFT_MASK) and event.keyval in self.SPACE_KEY_VAL: return self.show_completion() if not (library.loaded) and library.valid_accelerator(event.keyval, event.state): library.ensure_files() library.ensure(self.language_id) self.accelerator_activate(event.keyval, event.state & gtk.accelerator_get_default_mod_mask()) return False def path_split(self, path, components = []): (head, tail) = os.path.split(path) if not tail and head: return [ head] + components if tail: return self.path_split(head, [ tail] + components) return components def relative_filename(self, first, second, mime): prot1 = re.match('(^[a-z]+:\\/\\/|\\/)(.*)', first) prot2 = re.match('(^[a-z]+:\\/\\/|\\/)(.*)', second) if not prot1 or not prot2: return second if prot1.group(1) != prot2.group(1): return second path1 = self.path_split(prot1.group(2)) path2 = self.path_split(prot2.group(2)) while path1 and path2 and path1[0] == path2[0]: path1.pop(0) path2.pop(0) continue prot1.group(1) != prot2.group(1) if len(path1) - 1 > 3: return second if mime.startswith('x-directory'): if not path2: result = './' else: result = '../' * (len(path1) - 1) else: result = '../' * (len(path1) - 1) if not path2: result = os.path.basename(second) if path2: result += os.path.join(*path2) return result def apply_uri_snippet(self, snippet, mime, uri): if gedit.utils.uri_has_file_scheme(uri): gfile = gio.File(uri) uri = gfile.get_path() filename = self.env_get_filename(self.view.get_buffer()) os.environ['GEDIT_DROP_FILENAME'] = uri os.environ['GEDIT_DROP_MIME_TYPE'] = mime os.environ['GEDIT_DROP_REL_FILENAME'] = self.relative_filename(filename, uri, mime) buf = self.view.get_buffer() mark = buf.get_mark('gtk_drag_target') if not mark: mark = buf.get_insert() piter = buf.get_iter_at_mark(mark) self.apply_snippet(snippet, piter, piter) def in_bounds(self, x, y): rect = self.view.get_visible_rect() (rect.x, rect.y) = self.view.buffer_to_window_coords(gtk.TEXT_WINDOW_WIDGET, rect.x, rect.y) if not x < rect.x and x > rect.x + rect.width and y < rect.y: pass return not (y > rect.y + rect.height) def on_drag_data_received(self, view, context, x, y, data, info, timestamp): if not gtk.targets_include_uri(context.targets) and data.data and self.in_bounds(x, y): return None uris = drop_get_uris(data) uris.reverse() stop = False for uri in uris: try: mime = gio.content_type_guess(uri) except: self.in_bounds(x, y) mime = None if not mime: continue snippets = Library().from_drop_target(mime, self.language_id) if snippets: stop = True self.apply_uri_snippet(snippets[0], mime, uri) continue if stop: context.finish(True, False, timestamp) view.stop_emission('drag-data-received') view.get_toplevel().present() view.grab_focus() def find_uri_target(self, context): lst = gtk.target_list_add_uri_targets((), 0) return self.view.drag_dest_find_target(context, lst)